import { useMemberStore } from '@/stores'
import type { token } from '@/types/member'
import { apiName, apiUrl } from '@/config'
import _, { reject } from 'lodash'
import { pageUrl } from '@/utils/constants'
import { ref } from 'vue'

//配置拦截器
const Interceptor = {
  //拦截前触发
  invoke(options: UniApp.RequestOptions) {
    //拼接请求地址
    if (!options.url.startsWith('http') || !options.url.startsWith('https')) {
      // /api是系统保留的接口，不代理
      if (options.url.startsWith('/api')) {
        options.url = apiUrl + options.url
      } else {
        options.url = apiUrl + apiName + options.url
      }
    }
    //请求超时 10s
    options.timeout = 10000
    //请求头
    let sourceClient = ''
    switch (uni.getSystemInfoSync().uniPlatform) {
      case 'web':
        sourceClient = 'h5'
        break
      case 'mp-weixin':
        sourceClient = 'miniapp'
        break
      default:
        sourceClient = ''
    }
    options.header = {
      'source-client': sourceClient,
      server: true,
      ...options.header,
    }
    const memberStore = useMemberStore()
    const token = memberStore?.profile?.token || ''
    const refreshToken = memberStore.profile?.refresh_token || ''
    if (options.url.endsWith('/login/refresh')) {
      options.header['Ba-User-Refresh'] = refreshToken
    } else {
      options.header['Ba-User-Token'] = token
    }
  },
}

//拦截request请求
uni.addInterceptor('request', Interceptor)
//拦截文件上传请求
uni.addInterceptor('uploadFile', Interceptor)

//定义接口请求类型
interface Data<T> {
  msg: string
  result: T
}

const loginFail = (res: any) => {
  useMemberStore().clearProfile()
  uni.showModal({
    title: '温馨提示',
    content: '登录解锁更多精彩,是否继续?',
    confirmText: '去登录',
    cancelText: '再看看',
    success: function (res) {
      if (res.confirm) {
        uni.navigateTo({ url: pageUrl['login'] })
      } else {
        uni.navigateBack()
      }
    },
  })
  return reject(res)
}

const requestLoading = ref(false)
export const request = <T>(
  options: UniApp.RequestOptions,
  showBackModal = true,
  showLoading = true,
) => {
  return new Promise<Data<T>>((resolve, reject) => {
    if (showLoading) {
      wx.showLoading({
        title: '数据加载中…',
        mask: true,
      })
      requestLoading.value = true
    }
    uni.request({
      ...options,
      success(res) {
        if (requestLoading.value) {
          wx.hideLoading()
        }
        //成功
        if (res.statusCode === 200) {
          return resolve(res.data as Data<T>)
        }
        //服务器错误
        if (res.statusCode === 500) {
          if (requestLoading.value) {
            wx.hideLoading()
          }
          if (showBackModal) {
            uni.showModal({
              title: '',
              content: (res.data as Data<T>).msg || '服务器内部错误',
              success: function (res) {
                uni.navigateBack()
              },
            })
            uni.$emit('z-paging-error-emit')
          }
          return reject(res)
        }
        //参数错误
        if (res.statusCode === 400) {
          if (requestLoading.value) {
            wx.hideLoading()
          }
          uni.showToast({
            title: (res.data as Data<T>).msg || '请求数据异常',
            icon: 'none',
            mask: true,
            duration: 2500,
          })
          uni.$emit('z-paging-error-emit')
          return reject(res)
        }
        //登录态过期
        if (res.statusCode === 409) {
          const memberStore = useMemberStore()
          if (!memberStore.profile?.refresh_token) {
            return loginFail(res)
          }
          //通过refresh_token刷新token
          uni.request({
            url: '/login/refresh',
            method: 'POST',
            success(res) {
              if (res.statusCode != 200) {
                return loginFail(res)
              }
              //更新token
              memberStore.updateToken((res.data as Data<T>).result as token)
              //重新发起请求
              request<T>(options)
                .then((res) => {
                  return resolve(res)
                })
                .catch((err) => {
                  return reject(err)
                })
            },
            fail(err) {
              return loginFail(err)
            },
          })
        }
        //登录失效
        if (res.statusCode === 401) {
          if (requestLoading.value) {
            wx.hideLoading()
          }
          useMemberStore().clearProfile()
          return loginFail(res)
        }
      },
      //失败
      fail(err) {
        uni.showToast({
          title: '网络请求异常',
          icon: 'error',
        })
        uni.$emit('z-paging-error-emit')
        return reject(err)
      },
    })
  })
}
